package com.stars.easyms.alarm.util;

import com.stars.easyms.alarm.bean.EasyMsAlarmTraceInfo;
import com.stars.easyms.alarm.bean.EasyMsExceptionAlarmTraceInfo;
import com.stars.easyms.alarm.bean.EasyMsNormalAlarmTraceInfo;
import com.stars.easyms.alarm.factory.AlarmRestTemplateFactory;
import com.stars.easyms.alarm.message.EasyMsExceptionAlarmMessage;
import com.stars.easyms.alarm.message.EasyMsNormalAlarmMessage;
import com.stars.easyms.base.bean.EasyMsRequestEntity;
import com.stars.easyms.base.trace.EasyMsTraceSynchronizationManager;
import com.stars.easyms.base.util.ExceptionUtil;
import com.stars.easyms.base.util.SpringBootUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;

import static com.stars.easyms.alarm.constant.EasyMsAlarmConstant.MAX_EXCEPTION_MSG_LENGTH;

/**
 * <p>className: EasyMsAlarmUtil</p>
 * <p>description: EasyMs告警模块公共工具类</p>
 *
 * @author guoguifang
 * @version 1.6.1
 * @date 2020/8/24 10:13 上午
 */
public final class EasyMsAlarmUtil {

    /**
     * 发送告警信息
     *
     * @param webHook      发送地址
     * @param alarmMessage 告警消息
     * @return 响应结果
     */
    @NonNull
    public static <T> ResponseEntity<T> sendAlarmMessage(String webHook, Object alarmMessage, Class<T> responseType) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Object> entity = new HttpEntity<>(alarmMessage, headers);
        return AlarmRestTemplateFactory.getRestTemplate().postForEntity(webHook, entity, responseType);
    }

    public static EasyMsExceptionAlarmMessage getExceptionAlarmMessage(Throwable throwable) {
        EasyMsExceptionAlarmTraceInfo exceptionAlarmTraceInfo = new EasyMsExceptionAlarmTraceInfo();
        setAlarmTraceInfo(exceptionAlarmTraceInfo);
        exceptionAlarmTraceInfo.setExceptionClassName(throwable.getClass().getName());
        exceptionAlarmTraceInfo.setExceptionMessage(getThrowableMessage(throwable));
        exceptionAlarmTraceInfo.setFirstExceptionStack(ExceptionUtil.getFirstExceptionStack(throwable));
        EasyMsExceptionAlarmMessage exceptionAlarmMessage = new EasyMsExceptionAlarmMessage();
        exceptionAlarmMessage.setExceptionTraceInfo(exceptionAlarmTraceInfo);
        return exceptionAlarmMessage;
    }

    public static EasyMsNormalAlarmMessage getNormalAlarmMessage(String message) {
        EasyMsNormalAlarmTraceInfo normalAlarmTraceInfo = new EasyMsNormalAlarmTraceInfo();
        setAlarmTraceInfo(normalAlarmTraceInfo);
        normalAlarmTraceInfo.setAlarmMessage(message);
        EasyMsNormalAlarmMessage normalAlarmMessage = new EasyMsNormalAlarmMessage();
        normalAlarmMessage.setNormalAlarmTraceInfo(normalAlarmTraceInfo);
        return normalAlarmMessage;
    }

    private static void setAlarmTraceInfo(EasyMsAlarmTraceInfo alarmTraceInfo) {
        alarmTraceInfo.setApplicationName(SpringBootUtil.getApplicationName());
        alarmTraceInfo.setEnv(SpringBootUtil.getActiveProfile());
        alarmTraceInfo.setAlarmTime(System.currentTimeMillis());
        EasyMsRequestEntity requestEntity = EasyMsTraceSynchronizationManager.getRequestEntity();
        if (requestEntity != null) {
            alarmTraceInfo.setRequestSys(requestEntity.getRequestSys());
            alarmTraceInfo.setRequestPath(requestEntity.getRequestPath());
            alarmTraceInfo.setRequestId(requestEntity.getRequestId());
            alarmTraceInfo.setTraceId(requestEntity.getTraceId());
            // 由于异步id是随线程变化而变化的，因此需要实时获取，不在EasyMsRequestEntity对象里获取
            alarmTraceInfo.setAsyncId(EasyMsTraceSynchronizationManager.getAsyncId());
        } else {
            String traceId = EasyMsTraceSynchronizationManager.getTraceId();
            if (StringUtils.isNotBlank(traceId)) {
                alarmTraceInfo.setRequestId(EasyMsTraceSynchronizationManager.getRequestId());
                alarmTraceInfo.setTraceId(traceId);
                alarmTraceInfo.setAsyncId(EasyMsTraceSynchronizationManager.getAsyncId());
            }
        }
    }

    private static String getThrowableMessage(Throwable throwable) {
        String message = throwable.getMessage();
        if (message != null && message.length() > MAX_EXCEPTION_MSG_LENGTH) {
            message = message.substring(0, MAX_EXCEPTION_MSG_LENGTH) + "...(详细信息请查看日志)";
        }
        return message;
    }

    private EasyMsAlarmUtil() {}
}
